package com.tengju.user.infrastructure.repository.club;

import com.tengju.user.domain.model.club.ClubId;
import com.tengju.user.domain.model.club.ClubMemberRepository;
import com.tengju.user.domain.model.user.UserId;
import com.tengju.user.domain.model.user.UserIdCode;
import com.tengju.user.domain.model.user.UserInfo;
import com.tengju.user.infrastructure.persistence.mybatis.dataobject.ClubMemberDO;
import com.tengju.user.infrastructure.persistence.mybatis.mapper.dealer.custom.ClubMemberDOCustomMapper;
import com.tengju.user.infrastructure.persistence.mybatis.mapper.dealer.generate.ClubMemberDOMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author chenhang
 * @Date 2021/1/13
 */
@Repository
@RequiredArgsConstructor(onConstructor_ = {@Autowired})
public class ClubMemberRepositoryImpl implements ClubMemberRepository {

    private final ClubMemberDOMapper clubMemberDOMapper;
    private final ClubMemberDOCustomMapper clubMemberDOCustomMapper;

    @Override
    @Transactional(value = "dealerTransactionManager", rollbackFor = Exception.class)
    public void addClubMember(ClubId clubId, List<UserInfo> members) {
        if (CollectionUtils.isEmpty(members)) {
            return ;
        }
        List<ClubMemberDO> clubMemberDOS = members.stream()
                .map(v -> {
                    ClubMemberDO clubMemberDO = new ClubMemberDO();
                    clubMemberDO.setClubId(clubId.getValue());
                    clubMemberDO.setMemberIdCode(v.getIdCode().getValue());
                    clubMemberDO.setMemberUserId(v.getUserId().getValue());
                    return clubMemberDO;
                })
                .collect(Collectors.toList());
        clubMemberDOS.forEach(clubMemberDOMapper::insertSelective);
    }

    @Override
    public ClubId findClubIdByIdCode(UserIdCode idCode) {
        if (idCode == null) {
            return null;
        }
        Long clubId = clubMemberDOCustomMapper.findClubIdByIdCode(idCode.getValue());
        if (clubId == null) {
            return null;
        }
        return new ClubId(clubId);
    }

    @Override
    public void changeClub(UserIdCode idCode, ClubId newClubId) {
        clubMemberDOCustomMapper.changeClub(idCode.getValue(),newClubId.getValue());
    }

    @Override
    public Map<ClubId, List<Long>> batchGetMembers(List<ClubId> clubIds) {
        List<Long> clubIdValues = clubIds.stream().map(ClubId::getValue).collect(Collectors.toList());
        List<ClubMemberDO> clubMemberDOS = clubMemberDOCustomMapper.listMembers(clubIdValues);
        return clubMemberDOS.stream()
                .collect(Collectors.groupingBy(
                        v -> new ClubId(v.getClubId()),
                        Collectors.mapping(ClubMemberDO::getMemberIdCode, Collectors.toList())
                ));
    }

    @Override
    public void removeMember(UserIdCode idCode, ClubId clubId) {
        clubMemberDOCustomMapper.delMember(idCode.getValue(),clubId.getValue());
    }

    @Override
    public List<UserIdCode> getMembers(ClubId clubId) {
        List<ClubMemberDO> clubMemberDOList = clubMemberDOCustomMapper.queryMembers(clubId.getValue());

        if (CollectionUtils.isEmpty(clubMemberDOList)){
            return null;
        }

        return clubMemberDOList.stream()
                .map(ClubMemberDO::getMemberIdCode)
                .map(UserIdCode::new)
                .collect(Collectors.toList());
    }
}
